package com.kws.payment.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import com.chinaums.open.api.OpenApiCache;
import com.chinaums.open.api.OpenApiContext;
import com.chinaums.open.api.constants.ConfigBean;
import com.chinaums.open.api.internal.util.http.HttpTransport;
import com.kws.common.core.exception.ServiceException;
import com.kws.common.core.utils.StringUtils;
import com.kws.payment.dao.*;
import com.kws.payment.dao.info.CreateAppUnionPayOrderInfo;
import com.kws.payment.dao.info.PaymentCallbackInfo;
import com.kws.payment.service.UnionAPPPayService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.UUID;

/**
 * <b>UnionAPPPayServiceImpl</b>
 *
 * @description: UnionAPPPayServiceImpl <br>
 * @date: 2024/12/25 09:25 <br>
 * @author: lhm <br>
 * @version: 1.0 <br>
 */

@Service
public class UnionAPPPayServiceImpl implements UnionAPPPayService {
    private static final Logger logger = LoggerFactory.getLogger(UnionAPPPayServiceImpl.class);

    /**
     * 银联分配appid
     */
    public String appId = "10037e6f6a4e6da4016a67b9789c0013";

    /**
     * 银联分配appkey
     */
    public String appKey = "ac2e1c592cee4d1ba0913864dd7d0dda";

    /**
     * 商户号
     */
    public String mid = "898201612345678";

    /**
     * 终端号
     */
    public String tid = "88880001";

    /**
     * 微信子商户appId 值为app应用在微信开放平台分配的appid
     */
    public String subAppId = "11111111";

    /**
     * 支付回调地址
     */
    public String notifyUrl = "";

    /**
     * 银联支付微信下单地址
     */
    public String unionPayAppWeixinOrderUrl = "https://api-mop.chinaums.com/v1/netpay/wx/unified-order";

    /**
     * 银联支付支付宝下单地址
     */
    public String unionPayAppAliOrderUrl = "https://test-api-open.chinaums.com/v1/netpay/trade/precreate";

    /**
     * 银联云闪付下单地址
     */
    public String yunFlashPayUrl = "https://test-api-open.chinaums.com/v1/netpay/uac/app-order";

    /**
     * 银联退款地址
     */
    public String refundUrl = "https://api-mop.chinaums.com/v1/netpay/refund";

    /**
     * 银联支付取消订单地址
     */
    public String closeUnionPayOrderUrl = "https://api-mop.chinaums.com/v1/netpay/close";

    /**
     * 银联支付微信下单
     * @param rq
     * @return
     * @throws Exception
     */
    @Override
    public CreateAppUnionPayOrderInfo createAppWeixinUnionPayOrder(CreateAppUnionPayOrderRq rq) throws Exception {
        UnionPayAppOrderRq unionPayAppOrderRq = new UnionPayAppOrderRq();
        BeanUtil.copyProperties(rq,unionPayAppOrderRq);
        unionPayAppOrderRq.setRequestTimestamp(DateUtil.format(new Date(), DatePattern.NORM_DATETIME_FORMATTER));
        unionPayAppOrderRq.setMid(mid);
        unionPayAppOrderRq.setTid(tid);
        unionPayAppOrderRq.setSubAppId(subAppId);
        unionPayAppOrderRq.setMerOrderId(rq.getOrderNo());
        unionPayAppOrderRq.setNotifyUrl(notifyUrl);//支付回调地址
        unionPayAppOrderRq.setDivisionFlag(true);
        unionPayAppOrderRq.setPlatformAmount(0);
        ConfigBean configBean = new ConfigBean();
        OpenApiContext context = new OpenApiContext();
        context.setStartTime(System.currentTimeMillis());
        context.setRequestId(UUID.randomUUID().toString().replace("-", ""));
        context.setOpenServUrl(unionPayAppWeixinOrderUrl.split("/v")[0].concat("/"));
        context.setApiServiceUrl(unionPayAppWeixinOrderUrl);
        context.setVersion(unionPayAppWeixinOrderUrl.split("/")[3]);
        context.setAppId(appId);
        context.setAppKey(appKey);
        context.setConfigBean(configBean);
        context.setServiceCode(unionPayAppWeixinOrderUrl.split("/v")[1].substring(1));
        OpenApiCache.getCurrentToken(context);
        //发起微信下单请求
        String respond = HttpTransport.getInstance().doPost(context, JSONUtil.toJsonStr(unionPayAppOrderRq));
        logger.info("获取微信下单返回结果："+respond);
        if (StringUtils.isEmpty(respond)){
            throw new ServiceException("下单失败！",30001);
        }
        CreateAppUnionPayOrderInfo info = JSONUtil.toBean(JSONUtil.parseObj(respond), CreateAppUnionPayOrderInfo.class);
        if (!"SUCCESS".equals(info.getErrCode())){
            throw new ServiceException(info.getErrMsg(),30002);
        }
        return info;
    }

    /**
     * 银联支付-支付宝下单
     * @param rq
     * @return CreateAppUnionPayOrderInfo
     */
    @Override
    public CreateAppUnionPayOrderInfo createAppAliUnionPayOrder(CreateAppUnionPayOrderRq rq) throws Exception {
        UnionPayAppOrderRq unionPayAppOrderRq = new UnionPayAppOrderRq();
        BeanUtil.copyProperties(rq,unionPayAppOrderRq);
        unionPayAppOrderRq.setRequestTimestamp(DateUtil.format(new Date(), DatePattern.NORM_DATETIME_FORMATTER));
        unionPayAppOrderRq.setMid(mid);
        unionPayAppOrderRq.setTid(tid);
        unionPayAppOrderRq.setMerOrderId(rq.getOrderNo());
        unionPayAppOrderRq.setNotifyUrl(notifyUrl);//支付回调地址
        unionPayAppOrderRq.setDivisionFlag(true);
        unionPayAppOrderRq.setPlatformAmount(0);
        ConfigBean configBean = new ConfigBean();
        OpenApiContext context = new OpenApiContext();
        context.setStartTime(System.currentTimeMillis());
        context.setRequestId(UUID.randomUUID().toString().replace("-", ""));
        context.setOpenServUrl(unionPayAppAliOrderUrl.split("/v")[0].concat("/"));
        context.setApiServiceUrl(unionPayAppAliOrderUrl);
        context.setVersion(unionPayAppAliOrderUrl.split("/")[3]);
        context.setAppId(appId);
        context.setAppKey(appKey);
        context.setConfigBean(configBean);
        context.setServiceCode(unionPayAppAliOrderUrl.split("/v")[1].substring(1));
        OpenApiCache.getCurrentToken(context);
        //发起微信下单请求
        String respond = HttpTransport.getInstance().doPost(context, JSONUtil.toJsonStr(unionPayAppOrderRq));
        logger.info("获取银联支付支付宝下单返回结果："+respond);
        if (StringUtils.isEmpty(respond)){
            throw new ServiceException("下单失败！",30001);
        }
        CreateAppUnionPayOrderInfo info = JSONUtil.toBean(JSONUtil.parseObj(respond), CreateAppUnionPayOrderInfo.class);
        if (!"SUCCESS".equals(info.getErrCode())){
            throw new ServiceException(info.getErrMsg(),30002);
        }
        return info;
    }

    /**
     * 云闪付下单
     * @param rq
     * @return
     */
    @Override
    public CreateAppUnionPayOrderInfo createAppYunFlashPayOrder(CreateAppUnionPayOrderRq rq) throws Exception {
        UnionPayAppOrderRq unionPayAppOrderRq = new UnionPayAppOrderRq();
        BeanUtil.copyProperties(rq,unionPayAppOrderRq);
        unionPayAppOrderRq.setRequestTimestamp(DateUtil.format(new Date(), DatePattern.NORM_DATETIME_FORMATTER));
        unionPayAppOrderRq.setMid(mid);
        unionPayAppOrderRq.setTid(tid);
        unionPayAppOrderRq.setMerOrderId(rq.getOrderNo());
        unionPayAppOrderRq.setNotifyUrl(notifyUrl);//支付回调地址
        unionPayAppOrderRq.setDivisionFlag(true);
        unionPayAppOrderRq.setPlatformAmount(0);
        ConfigBean configBean = new ConfigBean();
        OpenApiContext context = new OpenApiContext();
        context.setStartTime(System.currentTimeMillis());
        context.setRequestId(UUID.randomUUID().toString().replace("-", ""));
        context.setOpenServUrl(yunFlashPayUrl.split("/v")[0].concat("/"));
        context.setApiServiceUrl(yunFlashPayUrl);
        context.setVersion(yunFlashPayUrl.split("/")[3]);
        context.setAppId(appId);
        context.setAppKey(appKey);
        context.setConfigBean(configBean);
        context.setServiceCode(yunFlashPayUrl.split("/v")[1].substring(1));
        OpenApiCache.getCurrentToken(context);
        //发起微信下单请求
        String respond = HttpTransport.getInstance().doPost(context, JSONUtil.toJsonStr(unionPayAppOrderRq));
        logger.info("获取银联云闪付下单返回结果："+respond);
        if (StringUtils.isEmpty(respond)){
            throw new ServiceException("下单失败！",30001);
        }
        CreateAppUnionPayOrderInfo info = JSONUtil.toBean(JSONUtil.parseObj(respond), CreateAppUnionPayOrderInfo.class);
        if (!"SUCCESS".equals(info.getErrCode())){
            throw new ServiceException(info.getErrMsg(),30002);
        }
        return info;
    }

    /**
     * 取消银联支付下单
     * @param orderNo
     * @return
     */
    @Override
    public CreateAppUnionPayOrderInfo closeUnionPayOrder(String orderNo) throws Exception {
        CancelUnionPayOrderRq cancelUnionPayOrderRq = new CancelUnionPayOrderRq();
        cancelUnionPayOrderRq.setRequestTimestamp(DateUtil.format(new Date(), DatePattern.NORM_DATETIME_FORMATTER));
        cancelUnionPayOrderRq.setInstMid("APPDEFAULT");
        cancelUnionPayOrderRq.setMerOrderId(orderNo);
        cancelUnionPayOrderRq.setMid(mid);
        cancelUnionPayOrderRq.setTid(tid);
        ConfigBean configBean = new ConfigBean();
        OpenApiContext context = new OpenApiContext();
        context.setStartTime(System.currentTimeMillis());
        context.setRequestId(UUID.randomUUID().toString().replace("-", ""));
        context.setOpenServUrl(closeUnionPayOrderUrl.split("/v")[0].concat("/"));
        context.setApiServiceUrl(closeUnionPayOrderUrl);
        context.setVersion(closeUnionPayOrderUrl.split("/")[3]);
        context.setAppId(appId);
        context.setAppKey(appKey);
        context.setConfigBean(configBean);
        context.setServiceCode(closeUnionPayOrderUrl.split("/v")[1].substring(1));
        OpenApiCache.getCurrentToken(context);
        //发起微信下单请求
        String respond = HttpTransport.getInstance().doPost(context, JSONUtil.toJsonStr(cancelUnionPayOrderRq));
        if (StringUtils.isNotEmpty(respond)){
            throw new ServiceException("取消银联支付订单失败！请稍后再试",30003);
        }
        CreateAppUnionPayOrderInfo info = JSONUtil.toBean(JSONUtil.parseObj(respond), CreateAppUnionPayOrderInfo.class);
        if (!"SUCCESS".equals(info.getErrCode())){
            throw new ServiceException(info.getErrMsg(),30002);
        }
        return info;
    }

    /**
     * 银联支付退款申请
     * @param rq
     * @return
     */
    @Override
    public CreateAppUnionPayOrderInfo unionPayAppRefund(UnionPayRefundRq rq) throws Exception {
        UnionPayRefund unionPayRefund = new UnionPayRefund();
        unionPayRefund.setRequestTimestamp(DateUtil.format(new Date(), DatePattern.NORM_DATETIME_FORMATTER));
        unionPayRefund.setMerOrderId(rq.getOrderNo());
        unionPayRefund.setInstMid("APPDEFAULT");
        unionPayRefund.setMsgId(mid);
        unionPayRefund.setTid(tid);
        unionPayRefund.setRefundAmount(rq.getRefundAmount());
        unionPayRefund.setTargetOrderId(rq.getTargetOrderId());
        unionPayRefund.setRefundOrderId(rq.getRefundOrderId());
        unionPayRefund.setPlatformAmount(0);
        unionPayRefund.setSubOrders(rq.getSubOrders());
        unionPayRefund.setRefundDesc(rq.getRefundDesc());
        ConfigBean configBean = new ConfigBean();
        OpenApiContext context = new OpenApiContext();
        context.setStartTime(System.currentTimeMillis());
        context.setRequestId(UUID.randomUUID().toString().replace("-", ""));
        context.setOpenServUrl(refundUrl.split("/v")[0].concat("/"));
        context.setApiServiceUrl(refundUrl);
        context.setVersion(refundUrl.split("/")[3]);
        context.setAppId(appId);
        context.setAppKey(appKey);
        context.setConfigBean(configBean);
        context.setServiceCode(refundUrl.split("/v")[1].substring(1));
        OpenApiCache.getCurrentToken(context);
        //发起银联退款请求
        String respond = HttpTransport.getInstance().doPost(context, JSONUtil.toJsonStr(unionPayRefund));
        if (StringUtils.isNotEmpty(respond)){
            throw new ServiceException("退款失败！请稍后再试",30004);
        }
        CreateAppUnionPayOrderInfo info = JSONUtil.toBean(JSONUtil.parseObj(respond), CreateAppUnionPayOrderInfo.class);
        if (!"SUCCESS".equals(info.getErrCode())){
            throw new ServiceException(info.getErrMsg(),30002);
        }
        return info;
    }

    /**
     * 支付/退款结果通知
     * @param resultInfo
     */
    @Override
    public void unionPayPaymentResult(PaymentCallbackInfo resultInfo) {
        if ("TRADE_SUCCESS".equals(resultInfo.getStatus())){
            logger.info("订单号："+resultInfo.getMerOrderId()+"支付成功");

        }
    }

}
